home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 March / PCWorld_2001-03_cd.bin / Software / TemaCD / classbuild / ClassBuilder 2.2 PR405 Setup.exe / {app} / Include / CB_ValueTree.h < prev    next >
C/C++ Source or Header  |  2000-04-06  |  23KB  |  720 lines

  1. #ifndef CB_VALUETREE_H
  2. #define CB_VALUETREE_H
  3.  
  4. #include <assert.h>
  5.  
  6. #include "CB_IteratorMulti.h"
  7.  
  8. // defines for include files
  9. #define RELATION_TEMPLATE_VALUETREE_ACTIVE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  10. private:\
  11.     ClassTo* _first##NameTo;\
  12.     int _count##NameTo;\
  13. \
  14. public:\
  15.     void Add##NameTo(ClassTo* item)\
  16.     {\
  17.         METHOD_VALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  18.     }\
  19.     void Remove##NameTo(ClassTo* item)\
  20.     {\
  21.         METHOD_VALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  22.     }\
  23.     void RemoveAll##NameTo()\
  24.     {\
  25.         METHOD_VALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  26.     }\
  27.     void DeleteAll##NameTo()\
  28.     {\
  29.         METHOD_VALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  30.     }\
  31.     void Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  32.     {\
  33.         METHOD_VALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  34.     }\
  35.     ClassTo* GetFirst##NameTo() const\
  36.     {\
  37.         METHOD_VALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  38.     }\
  39.     ClassTo* GetLast##NameTo() const\
  40.     {\
  41.         METHOD_VALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  42.     }\
  43.     ClassTo* GetNext##NameTo(ClassTo* pos) const\
  44.     {\
  45.         METHOD_VALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  46.     }\
  47.     ClassTo* GetPrev##NameTo(ClassTo* pos) const\
  48.     {\
  49.         METHOD_VALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  50.     }\
  51.     int Get##NameTo##Count() const\
  52.     {\
  53.         METHOD_VALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  54.     }\
  55.     ITERATOR_TEMPLATE_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  56.  
  57. #define RELATION_TEMPLATE_NOFILTER_VALUETREE_ACTIVE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  58. private:\
  59.     ClassTo* _first##NameTo;\
  60.     int _count##NameTo;\
  61. \
  62. public:\
  63.     void Add##NameTo(ClassTo* item)\
  64.     {\
  65.         METHOD_VALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  66.     }\
  67.     void Remove##NameTo(ClassTo* item)\
  68.     {\
  69.         METHOD_VALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  70.     }\
  71.     void RemoveAll##NameTo()\
  72.     {\
  73.         METHOD_VALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  74.     }\
  75.     void DeleteAll##NameTo()\
  76.     {\
  77.         METHOD_VALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  78.     }\
  79.     void Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  80.     {\
  81.         METHOD_VALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  82.     }\
  83.     ClassTo* GetFirst##NameTo() const\
  84.     {\
  85.         METHOD_VALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  86.     }\
  87.     ClassTo* GetLast##NameTo() const\
  88.     {\
  89.         METHOD_VALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  90.     }\
  91.     ClassTo* GetNext##NameTo(ClassTo* pos) const\
  92.     {\
  93.         METHOD_VALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  94.     }\
  95.     ClassTo* GetPrev##NameTo(ClassTo* pos) const\
  96.     {\
  97.         METHOD_VALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  98.     }\
  99.     int Get##NameTo##Count() const\
  100.     {\
  101.         METHOD_VALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  102.     }\
  103.     ITERATOR_TEMPLATE_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  104.  
  105. #define RELATION_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  106. private:\
  107.     ClassTo* _first##NameTo;\
  108.     int _count##NameTo;\
  109. \
  110. public:\
  111.     void Add##NameTo(ClassTo* item);\
  112.     void Remove##NameTo(ClassTo* item);\
  113.     void RemoveAll##NameTo();\
  114.     void DeleteAll##NameTo();\
  115.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  116.     ClassTo* GetFirst##NameTo() const;\
  117.     ClassTo* GetLast##NameTo() const;\
  118.     ClassTo* GetNext##NameTo(ClassTo* pos) const;\
  119.     ClassTo* GetPrev##NameTo(ClassTo* pos) const;\
  120.     int Get##NameTo##Count() const;\
  121.     ITERATOR_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  122.  
  123. #define RELATION_NOFILTER_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  124. private:\
  125.     ClassTo* _first##NameTo;\
  126.     int _count##NameTo;\
  127. \
  128. public:\
  129.     void Add##NameTo(ClassTo* item);\
  130.     void Remove##NameTo(ClassTo* item);\
  131.     void RemoveAll##NameTo();\
  132.     void DeleteAll##NameTo();\
  133.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  134.     ClassTo* GetFirst##NameTo() const;\
  135.     ClassTo* GetLast##NameTo() const;\
  136.     ClassTo* GetNext##NameTo(ClassTo* pos) const;\
  137.     ClassTo* GetPrev##NameTo(ClassTo* pos) const;\
  138.     int Get##NameTo##Count() const;\
  139.     ITERATOR_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  140.  
  141. #define RELATION_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  142. public:\
  143.     ClassFrom* _ref##NameFrom;\
  144.     ClassTo* _parent##NameFrom;\
  145.     ClassTo* _left##NameFrom;\
  146.     ClassTo* _right##NameFrom;\
  147.     ClassTo* _sibling##NameFrom;\
  148. \
  149. public:\
  150.     ClassFrom* Get##NameFrom() const { return _ref##NameFrom; };
  151.  
  152. // defines implementation
  153. #define INIT_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  154.     _first##NameTo = (ClassTo*)0;\
  155.     _count##NameTo = 0;
  156.  
  157. #define EXIT_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  158.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  159.           Remove##NameTo(item); }
  160.  
  161. #define REPLACE_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  162.     _first##NameTo = pOld->_first##NameTo;\
  163.     _count##NameTo = pOld->_count##NameTo;\
  164.     pOld->_first##NameTo = (ClassTo*)0;\
  165.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  166.           item->_ref##NameFrom = this; }
  167.  
  168. #define INIT_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  169.     _ref##NameFrom = (ClassFrom*)0;\
  170.     _parent##NameFrom = (ClassTo*)0;\
  171.     _left##NameFrom = (ClassTo*)0;\
  172.     _right##NameFrom = (ClassTo*)0;\
  173.     _sibling##NameFrom = (ClassTo*)0;
  174.  
  175. #define EXIT_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  176.     if (_ref##NameFrom)\
  177.         _ref##NameFrom->Remove##NameTo(this);
  178.  
  179. #define REPLACE_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  180.     _ref##NameFrom = (ClassFrom*)0;\
  181.     _parent##NameFrom = (ClassTo*)0;\
  182.     _left##NameFrom = (ClassTo*)0;\
  183.     _right##NameFrom = (ClassTo*)0;\
  184.     _sibling##NameFrom = (ClassTo*)0;\
  185.     if (pOld->_ref##NameFrom)\
  186.         pOld->_ref##NameFrom->Replace##NameTo(pOld, this);
  187.  
  188. #define REMOVE_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  189.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  190.       {\
  191.           (void)new UndoSubChange(item);\
  192.           Remove##NameTo(item);\
  193.       } }
  194.  
  195. #define SAVE_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  196.     p##ClassTo->_ref##NameFrom = _ref##NameFrom;
  197.  
  198. #define RESTORE_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  199.     {\
  200.         ClassFrom* p##ClassFrom = p##ClassTo->_ref##NameFrom;\
  201.         _ref##NameFrom = 0;\
  202.         p##ClassFrom->Add##NameTo(this);\
  203.     }\
  204.  
  205. #define REMOVE_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  206.     if (_ref##NameFrom)\
  207.     {\
  208.         ClassFrom* p##ClassFrom = _ref##NameFrom;\
  209.         _ref##NameFrom->Remove##NameTo(this);\
  210.         _ref##NameFrom = p##ClassFrom;\
  211.     }
  212.  
  213. #define CLEANUP_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  214.     _ref##NameFrom = (ClassFrom*)0;\
  215.     _parent##NameFrom = (ClassTo*)0;\
  216.     _left##NameFrom = (ClassTo*)0;\
  217.     _right##NameFrom = (ClassTo*)0;\
  218.     _sibling##NameFrom = (ClassTo*)0;
  219.  
  220. #define METHODS_VALUETREE_ACTIVE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  221. void ClassFrom##::Add##NameTo(ClassTo* item)\
  222. {\
  223.     METHOD_VALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  224. }\
  225. \
  226. void ClassFrom##::Remove##NameTo(ClassTo* item)\
  227. {\
  228.     METHOD_VALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  229. }\
  230. \
  231. void ClassFrom##::RemoveAll##NameTo()\
  232. {\
  233.     METHOD_VALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  234. }\
  235. \
  236. void ClassFrom##::DeleteAll##NameTo()\
  237. {\
  238.     METHOD_VALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  239. }\
  240. \
  241. void ClassFrom##::Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  242. {\
  243.     METHOD_VALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  244. }\
  245. \
  246. ClassTo* ClassFrom##::GetFirst##NameTo() const\
  247. {\
  248.     METHOD_VALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  249. }\
  250. \
  251. ClassTo* ClassFrom##::GetLast##NameTo() const\
  252. {\
  253.     METHOD_VALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  254. }\
  255. \
  256. ClassTo* ClassFrom##::GetNext##NameTo(ClassTo* pos) const\
  257. {\
  258.     METHOD_VALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  259. }\
  260. \
  261. ClassTo* ClassFrom##::GetPrev##NameTo(ClassTo* pos) const\
  262. {\
  263.     METHOD_VALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  264. }\
  265. \
  266. int ClassFrom##::Get##NameTo##Count() const\
  267. {\
  268.     METHOD_VALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  269. }
  270.  
  271. #define METHOD_VALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  272.     assert(this);\
  273. \
  274.     assert(item);\
  275.     assert(item->_ref##NameFrom == (ClassFrom*)0);\
  276. \
  277.     _count##NameTo++;\
  278. \
  279.     item->_ref##NameFrom = this;\
  280. \
  281.     if (_first##NameTo)\
  282.     {\
  283.         ClassTo* current = _first##NameTo;\
  284.         unsigned long bit = 0x1;\
  285.         while (1)\
  286.         {\
  287.             if(current->member != item->member)\
  288.             {\
  289.                 if ((current->member & bit) == (item->member & bit))\
  290.                 {\
  291.                     if (current->_left##NameFrom)\
  292.                     {\
  293.                         current = current->_left##NameFrom;\
  294.                     }\
  295.                     else\
  296.                     {\
  297.                         current->_left##NameFrom = item;\
  298.                         item->_parent##NameFrom = current;\
  299.                         break;\
  300.                     }\
  301.                 }\
  302.                 else\
  303.                 {\
  304.                     if (current->_right##NameFrom)\
  305.                     {\
  306.                         current = current->_right##NameFrom;\
  307.                     }\
  308.                     else\
  309.                     {\
  310.                         current->_right##NameFrom = item;\
  311.                         item->_parent##NameFrom = current;\
  312.                         break;\
  313.                     }\
  314.                 }\
  315. \
  316.                 bit <<= 1;\
  317.             }\
  318.             else\
  319.             {\
  320.                 item->_sibling##NameFrom = current->_sibling##NameFrom;\
  321.                 item->_parent##NameFrom = current;\
  322.                 current->_sibling##NameFrom = item;\
  323.                 if (item->_sibling##NameFrom)\
  324.                     item->_sibling##NameFrom->_parent##NameFrom = item;\
  325.                 break;\
  326.             }\
  327.         }\
  328.     }\
  329.     else\
  330.     {\
  331.         _first##NameTo = item;\
  332.     }
  333.  
  334. #define METHOD_VALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  335.     assert(this);\
  336. \
  337.     assert(item);\
  338.     assert(item->_ref##NameFrom == this);\
  339. \
  340.     ClassFrom##::##NameTo##Iterator::Check(item);\
  341. \
  342.     _count##NameTo--;\
  343. \
  344.     if (item->_parent##NameFrom && item->_parent##NameFrom->_sibling##NameFrom == item)\
  345.     {\
  346.         item->_parent##NameFrom->_sibling##NameFrom = item->_sibling##NameFrom;\
  347.         if (item->_sibling##NameFrom)\
  348.             item->_sibling##NameFrom->_parent##NameFrom = item->_parent##NameFrom;\
  349.     }\
  350.     else if (item->_sibling##NameFrom)\
  351.     {\
  352.         ClassTo* replacement = item->_sibling##NameFrom;\
  353.         replacement->_parent##NameFrom = item->_parent##NameFrom;\
  354.         replacement->_left##NameFrom = item->_left##NameFrom;\
  355.         if (item->_left##NameFrom)\
  356.             item->_left##NameFrom->_parent##NameFrom = replacement;\
  357.         replacement->_right##NameFrom = item->_right##NameFrom;\
  358.         if (item->_right##NameFrom)\
  359.             item->_right##NameFrom->_parent##NameFrom = replacement;\
  360. \
  361.         ClassTo* parent = item->_parent##NameFrom;\
  362.         if (parent)\
  363.         {\
  364.             if (parent->_left##NameFrom == item)\
  365.             {\
  366.                 parent->_left##NameFrom = replacement;\
  367.             }\
  368.             else\
  369.             {\
  370.                 parent->_right##NameFrom = replacement;\
  371.             }\
  372.         }\
  373.         else\
  374.         {\
  375.             _first##NameTo = replacement;\
  376.         }\
  377.     }\
  378.     else\
  379.     {\
  380.         ClassTo* replacement = 0;\
  381.         ClassTo* move = 0;\
  382.         if (item->_left##NameFrom)\
  383.         {\
  384.             replacement = item->_left##NameFrom;\
  385.             replacement->_parent##NameFrom = item->_parent##NameFrom;\
  386.             move = item->_right##NameFrom;\
  387.         }\
  388.         else if (item->_right##NameFrom)\
  389.         {\
  390.             replacement = item->_right##NameFrom;\
  391.             replacement->_parent##NameFrom = item->_parent##NameFrom;\
  392.         }\
  393.     \
  394.         ClassTo* parent = item->_parent##NameFrom;\
  395.         if (parent)\
  396.         {\
  397.             if (parent->_left##NameFrom == item)\
  398.             {\
  399.                 parent->_left##NameFrom = replacement;\
  400.             }\
  401.             else\
  402.             {\
  403.                 parent->_right##NameFrom = replacement;\
  404.             }\
  405.         }\
  406.         else\
  407.         {\
  408.             _first##NameTo = replacement;\
  409.         }\
  410.     \
  411.         if (replacement)\
  412.         {\
  413.             while (1)\
  414.             {\
  415.                 ClassTo* tmp = replacement->_right##NameFrom;\
  416.                 replacement->_right##NameFrom = move;\
  417.                 if (move)\
  418.                 {\
  419.                     move->_parent##NameFrom = replacement;\
  420.                 }\
  421.                 \
  422.                 if (!replacement->_left##NameFrom)\
  423.                 {\
  424.                     if (tmp)\
  425.                     {\
  426.                         replacement->_left##NameFrom = tmp;\
  427.                         tmp = 0;\
  428.                     }\
  429.                     else\
  430.                     {\
  431.                         break;\
  432.                     }\
  433.                 }\
  434.                 move = tmp;\
  435.                 replacement = replacement->_left##NameFrom;\
  436.             }\
  437.         }\
  438.     }\
  439. \
  440.     item->_ref##NameFrom = (ClassFrom*)0;\
  441.     item->_parent##NameFrom = (ClassTo*)0;\
  442.     item->_left##NameFrom = (ClassTo*)0;\
  443.     item->_right##NameFrom = (ClassTo*)0;\
  444.     item->_sibling##NameFrom = (ClassTo*)0;
  445.  
  446. #define METHOD_VALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  447.     assert(this);\
  448. \
  449.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  450.           Remove##NameTo(item);
  451.  
  452. #define METHOD_VALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  453.     assert(this);\
  454. \
  455.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  456.           delete item;
  457.  
  458. #define METHOD_VALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  459.     assert(this);\
  460. \
  461.     assert(item);\
  462.     assert(item->_ref##NameFrom == this);\
  463. \
  464.     assert(newItem);\
  465.     assert(newItem->_ref##NameFrom == (ClassFrom*)0);\
  466. \
  467.     if (item->member == newItem->member)\
  468.     {\
  469.         ClassFrom##::##NameTo##Iterator::Check(item, newItem);\
  470.         if (_first##NameTo == item)\
  471.         {\
  472.             _first##NameTo = newItem;\
  473.         }\
  474.         if (item->_parent##NameFrom)\
  475.         {\
  476.             if (item->_parent##NameFrom->_left##NameFrom == item)\
  477.             {\
  478.                 item->_parent##NameFrom->_left##NameFrom = newItem;\
  479.             }\
  480.             else if (item->_parent##NameFrom->_right##NameFrom == item)\
  481.             {\
  482.                 item->_parent##NameFrom->_right##NameFrom = newItem;\
  483.             }\
  484.             else if (item->_parent##NameFrom->_sibling##NameFrom == item)\
  485.             {\
  486.                 item->_parent##NameFrom->_sibling##NameFrom = newItem;\
  487.             }\
  488.         }\
  489.         newItem->_ref##NameFrom = this;\
  490.         newItem->_parent##NameFrom = item->_parent##NameFrom;\
  491.         newItem->_left##NameFrom = item->_left##NameFrom;\
  492.         newItem->_right##NameFrom = item->_right##NameFrom;\
  493.         newItem->_sibling##NameFrom = item->_sibling##NameFrom;\
  494.         item->_ref##NameFrom = (ClassFrom*)0;\
  495.         item->_parent##NameFrom = (ClassTo*)0;\
  496.         item->_left##NameFrom = (ClassTo*)0;\
  497.         item->_right##NameFrom = (ClassTo*)0;\
  498.         item->_sibling##NameFrom = (ClassTo*)0;\
  499.     }\
  500.     else\
  501.     {\
  502.         ClassFrom##::##NameTo##Iterator::Check(item);\
  503.         Remove##NameTo(item);\
  504.         Add##NameTo(newItem);\
  505.     }
  506.  
  507. #define METHOD_VALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  508.     assert(this);\
  509.     return _first##NameTo;
  510.  
  511. #define METHOD_VALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  512.     assert(this);\
  513. \
  514.     ClassTo* result = _first##NameTo;\
  515.     while (result)\
  516.     {\
  517.         while (result->_right##NameFrom)\
  518.         {\
  519.             result = result->_right##NameFrom;\
  520.         }\
  521. \
  522.         if (result->_left##NameFrom)\
  523.         {\
  524.             result = result->_left##NameFrom;\
  525.         }\
  526.         else\
  527.         {\
  528.             break;\
  529.         }\
  530.     }\
  531. \
  532.     if (result)\
  533.     {\
  534.         while (result->_sibling##NameFrom)\
  535.             result = result->_sibling##NameFrom;\
  536.     }\
  537. \
  538.     return result;
  539.  
  540. #define METHOD_VALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  541.     assert(this);\
  542. \
  543.     ClassTo* result = 0;\
  544.     if (pos == (ClassTo*)0)\
  545.         result = _first##NameTo;\
  546.     else\
  547.     {\
  548.         assert(pos->_ref##NameFrom == this);\
  549. \
  550.         if (pos->_sibling##NameFrom)\
  551.             result = pos->_sibling##NameFrom;\
  552.         else\
  553.         {\
  554.             while (pos->_parent##NameFrom && pos->_parent##NameFrom->_sibling##NameFrom == pos)\
  555.                 pos = pos->_parent##NameFrom;\
  556. \
  557.             if (pos->_left##NameFrom)\
  558.             {\
  559.                 result = pos->_left##NameFrom;\
  560.             }\
  561.             else\
  562.             {\
  563.                 if (pos->_right##NameFrom)\
  564.                 {\
  565.                     result = pos->_right##NameFrom;\
  566.                 }\
  567.                 else\
  568.                 {\
  569.                     ClassTo* parent = pos->_parent##NameFrom;\
  570.                     while (parent && (parent->_right##NameFrom == 0 || parent->_right##NameFrom == pos))\
  571.                     {\
  572.                         pos = parent;\
  573.                         parent = parent->_parent##NameFrom;\
  574.                     }\
  575. \
  576.                     if (parent)\
  577.                     {\
  578.                         result = parent->_right##NameFrom;\
  579.                     }\
  580.                 }\
  581.             }\
  582.         }\
  583.     }\
  584. \
  585.     return result;
  586.  
  587. #define METHOD_VALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  588.     assert(this);\
  589. \
  590.     ClassTo* result = 0;\
  591.     if (pos == (ClassTo*)0)\
  592.         result = GetLast##NameTo();\
  593.     else\
  594.     {\
  595.         assert(pos->_ref##NameFrom == this);\
  596. \
  597.         if (pos->_parent##NameFrom)\
  598.         {\
  599.             if (pos->_parent##NameFrom->_sibling##NameFrom == pos)\
  600.                 result = pos->_parent##NameFrom;\
  601.             else\
  602.             {\
  603.                 if (pos->_parent##NameFrom->_left##NameFrom == pos || pos->_parent##NameFrom->_left##NameFrom == 0)\
  604.                 {\
  605.                     result = pos->_parent##NameFrom;\
  606.                 }\
  607.                 else /* Right branche and valid left branche */\
  608.                 {\
  609.                     result = pos->_parent##NameFrom->_left##NameFrom;\
  610.                     while (1)\
  611.                     {\
  612.                         while (result->_right##NameFrom)\
  613.                         {\
  614.                             result = result->_right##NameFrom;\
  615.                         }\
  616. \
  617.                         if (result->_left##NameFrom)\
  618.                         {\
  619.                             result = result->_left##NameFrom;\
  620.                         }\
  621.                         else\
  622.                         {\
  623.                             break;\
  624.                         }\
  625.                     }\
  626.                 }\
  627.                 if (result)\
  628.                 {\
  629.                     while (result->_sibling##NameFrom)\
  630.                         result = result->_sibling##NameFrom;\
  631.                 }\
  632.             }\
  633.         }\
  634.     }\
  635. \
  636.     return result;
  637.  
  638. #define METHOD_VALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  639.     assert(this);\
  640.     return _count##NameTo;
  641.  
  642. #ifndef _BODY_VALUETREE_FIND
  643. #define _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  644.     ClassTo* result = 0;\
  645.     if (_first##NameTo)\
  646.     {\
  647.         ClassTo* item = _first##NameTo;\
  648.         unsigned long bit = 0x1;\
  649.         while (1)\
  650.         {\
  651.             if (item->member == value)\
  652.             {\
  653.                 result = item;\
  654.                 break;\
  655.             }\
  656. \
  657.             if ((item->member & bit) == (value & bit))\
  658.             {\
  659.                 if (item->_left##NameFrom)\
  660.                 {\
  661.                     item = item->_left##NameFrom;\
  662.                 }\
  663.                 else\
  664.                 {\
  665.                     break;\
  666.                 }\
  667.             }\
  668.             else\
  669.             {\
  670.                 if (item->_right##NameFrom)\
  671.                 {\
  672.                     item = item->_right##NameFrom;\
  673.                 }\
  674.                 else\
  675.                 {\
  676.                     break;\
  677.                 }\
  678.             }\
  679. \
  680.             bit <<= 1;\
  681.         }\
  682.     }
  683. #endif
  684.  
  685. #define BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  686.     _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  687.     return result;
  688.  
  689. #define BODY_VALUETREE_FINDREVERSE(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  690.     _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  691.     if (result)\
  692.     {\
  693.         while (result->_sibling##NameFrom)\
  694.             result = result->_sibling##NameFrom;\
  695.     }\
  696. \
  697.     return result;
  698.  
  699. #define METHODS_VALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  700.  
  701. #define WRITE_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  702.     rCArchive << Get##NameTo##Count();\
  703.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  704.           rCArchive << item->_index; }
  705.  
  706. #define READ_VALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  707.     {\
  708.         int count;\
  709.         int index;\
  710. \
  711.         rCArchive >> count;\
  712.         for (int i = 0; i < count; i++)\
  713.         {\
  714.             rCArchive >> index;\
  715.             Add##NameTo((ClassTo*)(pointerArray[index]));\
  716.         }\
  717.     }
  718.  
  719. #endif
  720.